/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package translationTable;

import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import nanoxml.XMLElement;

/**
 * This class represents the translation table and is able to know which elements 
 * can be traducted
 * @author Karim Naaji <karim.naaji@gmail.com>
 */
public class TranslationTable {

    XMLFileStream xfs;
    HashMap<String, String> supermap = new HashMap<String, String>();
    XMLElement root;

    public TranslationTable(URL url) {
        xfs = new XMLFileStream(url);
        root = xfs.getRoot();
        generate();
    }

    /**
     * Generates the translation table with the help of the XMLFileStream
     */
    public void generate() {

        Enumeration enumeration = root.enumerateChildren();
        XMLElement fonctionMadkit = (XMLElement) (enumeration.nextElement());
        //boucle sur toutes les fonctions du fichier
        while (enumeration.hasMoreElements()) {
            Enumeration enumerationFonction = fonctionMadkit.enumerateChildren();
            XMLElement fonctionJanus = (XMLElement) (enumerationFonction.nextElement());

            //préparation de la clef
            //j'ai décidé que le délimiteur du split serait le ; vu que c'est impossible de l'avoir dans un nom de fonction ou de classe
            String madkit = (fonctionMadkit.getAttribute("name").toString()+";"+fonctionMadkit.getAttribute("class").toString());

            //boucle sur les fonctions janus correspondant à la fonction madkit courante
            int compteur=0;
            while (enumerationFonction.hasMoreElements()) {

                //préparation de la valeur
                String janus = (fonctionJanus.getAttribute("name").toString()+";"+fonctionJanus.getAttribute("class").toString());
               //ajout dans la hashmap
                supermap.put(madkit, janus);
              
                fonctionJanus = (XMLElement) (enumerationFonction.nextElement());
                //je rajoute un indice à la fonction madkit pour repérer qu'elle est différente
                //des autres vu qu'elle est associée à une fonction janus différente... Je ne vois pas 
                //d'autre moyen de ne pas perdre l'info vu que les keys sont uniques
                compteur++;
                madkit=madkit+";"+compteur;
            }
            //itération bonus
            //préparation de la valeur
            String janus = (fonctionJanus.getAttribute("name").toString()+";"+fonctionJanus.getAttribute("class").toString());
            //notez que s'il n'y a qu'une fonction janus c'est ici que ça va (pas dans le while) et du coup
            //on a pas de compteur.
            //ajout dans la hashmap
            supermap.put(madkit, janus);



            fonctionMadkit = (XMLElement) (enumeration.nextElement());
        }
        Enumeration enumerationFonction = fonctionMadkit.enumerateChildren();
            XMLElement fonctionJanus = (XMLElement) (enumerationFonction.nextElement());

            //préparation de la clef
            String madkit = (fonctionMadkit.getAttribute("name").toString()+";"+fonctionMadkit.getAttribute("class").toString());
             
            //boucle sur les fonctions janus correspondant à la fonction madkit courante
            int compteur=0;
            while (enumerationFonction.hasMoreElements()) {
                
                //préparation de la valeur
                String janus = (fonctionJanus.getAttribute("name").toString()+";"+fonctionJanus.getAttribute("class").toString());
                
                //ajout dans la hashmap
                supermap.put(madkit, janus);

                fonctionJanus = (XMLElement) (enumerationFonction.nextElement());
                compteur++;
                madkit=madkit+";"+compteur;
            }
            //itération bonus
            //préparation de la valeur
            String janus = (fonctionJanus.getAttribute("name").toString()+";"+fonctionJanus.getAttribute("class").toString());
            //ajout dans la hashmap
            supermap.put(madkit, janus);
           
            
            //décommenter ce qui suit pour tester tout ça
            /*Method m=new Method();
            m.setName("autre");
            m.setClassName("AbstractAgent");
            System.out.print(getTranslation(m).get(0).getName());
            System.out.print(getTranslation(m).get(1).getName());*/
            
    }
    
    /**
     * return an array of all janus methods associated with the madkit function provided in parameter
     * @param the madkit method
     * @return an array of all corresponding janus methods 
     */
    public ArrayList<Method> getTranslation(Method madkitMethod) 
    {        
        ArrayList<Method> res= new ArrayList<Method>();
        //on reconcatène au bon format de la hashmap
        
        String requete = (madkitMethod.getName()+";"+madkitMethod.getClassName());
        //pour enlever les espaces qui traînent
        requete = requete.trim();
        
        //requête de base pour la première fonction janus
        if(supermap.get(requete)!=null)
        {
            //on récupère le résultat de la requête et on le split pour le renvoyer
            String[] tmp = supermap.get(requete).split(";");
            Method m=new Method();
            m.setName(tmp[0]);
            m.setClassName(tmp[1]);
            res.add(m);
        }else
            return null;
        
        //boucle sur les autres janus éventuelles
        int index=1;
        requete = (madkitMethod.getName()+";"+madkitMethod.getClassName()+";"+index);
        while(supermap.get(requete)!=null)
        {
            String[] tmp = supermap.get(requete).split(";");
            Method m=new Method();
            m.setName(tmp[0]);
            m.setClassName(tmp[1]);
            res.add(m);
            index++;
            requete = (madkitMethod.getName()+";"+madkitMethod.getClassName()+";"+index);
        }
        return res;
        
          
    }
    
   /* public ArrayList<Method> getClassEquivalent(String class){
        
    } */

    /**
     * Tell us if the key with the value is present in our translation table
     * @param value an array of two values (type String)
     */
    public boolean canBeTranslated(Method madkitMethod) {
        
        if(getTranslation(madkitMethod)!=null)
            return true;
        return false;
    }

}
